//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/buola.h>

#include <buola/io/cfdpoller.h>
#include <buola/io/cfdlistener.h>
#include <buola/io/cselectfdpoller.h>

#include <buola/algorithm/container.h>
#include <vector>

#include <cerrno>

namespace buola { namespace io {

std::vector<CFDPoller*> &all_fd_pollers()
{
    static std::vector<CFDPoller*> lP;
    return lP;
}
    
CFDPoller::CFDPoller()
    :   mEventLoop(nullptr)
{
    all_fd_pollers().push_back(this);
}

CFDPoller::CFDPoller(CEventLoop &pLoop)
    :   mEventLoop(&pLoop)
{
    pLoop.AddFunction(CEventLoop::PRIORITY_FDPOLLER,this,true);
    all_fd_pollers().push_back(this);
}

CFDPoller::~CFDPoller()
{
    erase_first_equal(all_fd_pollers(),this);
}

void CFDPoller::RemoveAllFDListeners(int pFD)
{
    for(auto i=all_fd_pollers().begin();i!=all_fd_pollers().end();++i)
    {
        (*i)->RemoveFDListeners(pFD);
    }
}

void CFDPoller::RemoveAllFDListeners(CFDListener *pListener)
{
    for(auto i=all_fd_pollers().begin();i!=all_fd_pollers().end();++i)
    {
        (*i)->RemoveFDListeners(pListener);
    }
}

bool CFDPoller::OnLoopFunction()
{
    return !WaitFDs(mEventLoop->CalcTimeout());
}

static CFDPoller *sMainFDPoller=nullptr;

void set_main_fd_poller(CFDPoller *pPoller)
{
    if(sMainFDPoller)
        throw XInvalid("can't set FD poller after it has already been used");
    sMainFDPoller=pPoller;
}

CFDPoller &get_main_fd_poller()
{
    if(!sMainFDPoller)
        sMainFDPoller=new CSelectFDPoller(get_main_event_loop());

    return *sMainFDPoller;
 }

/*namespace io*/ } /*namespace buola*/ }
